import asyncio
from logging import Logger

from fastapi import APIRouter, Depends
from requests import Session
from Util.ActivityUtil import get_detail, get_sign_code, sign_in_out, get_all_sign_activity, get_notice
from Util.AuthUtil import get_token
from Util.AutoSignApplyUtil import autoSignActivity
from config.Database import get_db
from config.Env import SystemUserInfo
from schemas.Activity import ActivityMyList
from schemas.Page import  PageCreate
from schemas.AccountUsage import AccountUsageUpdate, AccountUsageCreate
from schemas.Result import Result
from schemas.SignApplyInfo import SignApplyInfoCreate
from schemas.Submitinfo import SubmitInfoCreate, SubmitSign, SubmitTokenSign, SubmitInfoRequest
from services.AccountUsageServe import AccountUsageServe
from services.ActivityCache import ActivityCache
from services.ActivityNotStartCache import ActivityNotStartCache
from services.SignApplyInfoServe import SignApplyInfoServe
from services.SubmitInfoServe import SubmitInfoServe
from services.UserService import UserServe

router = APIRouter(
    prefix="/activity",
    tags=["activity"],
    responses={404: {"description": "Not found"}},
)
# 全局变量用于懒加载缓存实例
activity_cache_instance = None
activity_not_start_cache_instance = None
sign_apply_info_serve = SignApplyInfoServe()
@router.get("")
def get_all_notifications(db: Session = Depends(get_db)):
    # 获取首页的数据
    global activity_cache_instance
    page = PageCreate(pageNum=1, pageSize=99, sortType=1, status=5)
    # 懒加载：首次请求时初始化
    if activity_cache_instance is None:
        activity_cache_instance = ActivityCache(db, page)
    data = activity_cache_instance.get_activities()
    return Result.success(data,msg="success")

@router.get("/notStart")
def get_all_not_start_activity(db: Session = Depends(get_db)):
    # 获取首页的数据
    global activity_not_start_cache_instance
    page = PageCreate(pageNum=1, pageSize=99, sortType=1, status=4)
    # 懒加载：首次请求时初始化
    if activity_not_start_cache_instance is None:
        activity_not_start_cache_instance = ActivityNotStartCache(db, page)
    data = activity_not_start_cache_instance.get_activities()
    return Result.success(data, msg="success")

@router.post("")
async def submit(submitInfo: SubmitInfoRequest,db: Session = Depends(get_db)):
    # 验证用户凭据
    token = await get_token(submitInfo.username, submitInfo.password)
    if not token:
        return Result.fail(msg="用户名或密码错误")
    user_detail = None
    try:
        user_detail = await UserServe.save_user_info(token, db)
    except:
        Logger.error(f"{submitInfo.username}用户信息保存失败")
    # 验证用户使用次数
    account = AccountUsageServe.get_by_username(db, submitInfo.username)
    if not account:
        AccountUsageServe.create(db, AccountUsageCreate(username=submitInfo.username,count=-1,isdelete=False))
    elif account.count < -999:
        return Result.fail(msg="账号使用次数已用完或未授权，请联系管理员")
    try:
        # 判断一下用户是不是要自动签到
        await autoSignActivity(db=db, submitInfo=submitInfo, token=token, user_detail=user_detail)
        # 直接往数据里面插入数据 然后返回成功
        create = SubmitInfoServe.create(db, SubmitInfoCreate(username=submitInfo.username,password=submitInfo.password,email=submitInfo.email,ids=submitInfo.ids))
    except Exception as e:
        Result.fail(msg="提交失败")
    # 修改用户使用次数
    newAccount =  AccountUsageUpdate(username=account.username,count=account.count - 1,isdelete=False)
    AccountUsageServe.update(db,account.id,newAccount)

    if create:
        return Result.success(msg="提交成功")
    return Result.fail(msg="提交失败")

@router.get("/detail")
async def getDetail(id: int, db: Session = Depends(get_db)):
    # 测试接口 不对外开放
    data = await get_detail(id,SystemUserInfo.get_token())
    return Result.success(data)

@router.get("/signCode")
async def getSignCode(id: int, db: Session = Depends(get_db)):
    return await get_sign_code(id,SystemUserInfo.get_token())

@router.post("/sign")
async def sign(signInfo: SubmitSign, db: Session = Depends(get_db)):
    # 验证用户凭据
    token = await get_token(signInfo.username, signInfo.password)
    if not token:
        return Result.fail(msg="用户名或密码错误")

    # 验证用户使用次数
    account = AccountUsageServe.get_by_username(db, signInfo.username)
    if not account:
        AccountUsageServe.create(db, AccountUsageCreate(username=signInfo.username, count=-1, isdelete=False))
    elif account.count < -999:
        return Result.fail(msg="账号使用次数已用完或未授权，请联系管理员")
    # 修改用户使用次数
    newAccount = AccountUsageUpdate(username=account.username, count=account.count - 1, isdelete=False)
    AccountUsageServe.update(db, account.id, newAccount)


    #执行签到请求
    res = await sign_in_out(signInfo.activityId, token)
    return Result.success(msg=res.get('msg'))

# 直接通过token 来签到
@router.post("/userSign")
async def sign(signInfo: SubmitTokenSign, db: Session = Depends(get_db)):
    # 验证用户使用次数
    account = AccountUsageServe.get_by_username(db, signInfo.username)
    if not account:
        AccountUsageServe.create(db, AccountUsageCreate(username=signInfo.username, count=-1, isdelete=False))
    elif account.count < -999:
        return Result.fail(msg="账号使用次数已用完或未授权，请联系管理员")
    # 修改用户使用次数
    newAccount = AccountUsageUpdate(username=account.username, count=account.count - 1, isdelete=False)
    AccountUsageServe.update(db, account.id, newAccount)

    #执行签到请求
    res = await sign_in_out(signInfo.activityId, signInfo.token)
    if res.get('msg') == '签到签退开关未开启' or res.get('msg') == '非活动成员':
        return Result.fail(msg=res.get('msg'))

    return Result.success(msg=res.get('msg'))

@router.post("/myList")
async def get_my_list(signInfo: ActivityMyList, db: Session = Depends(get_db)):
    # 验证用户凭据
    token = await get_token(signInfo.username, signInfo.password)
    if not token:
        return Result.fail(msg="用户名或密码错误")
    res = await get_all_sign_activity(token)
    return ''

@router.get("/notice")
async def notice(id: int,db: Session = Depends(get_db)):
    data = await get_notice(id, SystemUserInfo.get_token())
    return Result.success(data['list'])
    pass

# 注册新活动推送
# 注册一个定时器, 每3分钟刷新一次 从缓存里面拿到未开始的新活动
# 然后跟上一次请求的数据做对比, 找到新的活动
# 如果有发现新的活动, 就查询数据库,找到订阅了新消息推送的用户email
# 以此发送邮箱推送